/*
 * @Author: wuqingchun
 * @Date: 2024-10-10 14:42:53
 * @Description: 
 * @LastEditors: wuqingchun
 * @LastEditTime: 2024-10-10 16:37:22
 */

#include <cstdio>
#include <cstring>
#include <cerrno>

#include <sys/socket.h>
#include <sys/select.h>
#include <sys/time.h>
#include <unistd.h>

#include "netperf_udp_server.h"


CNetperfUDPServer::CNetperfUDPServer(const NETPERF_PARAM_S& refParam):
    m_refParam(refParam)
{

}

CNetperfUDPServer::~CNetperfUDPServer()
{

}

int32_t CNetperfUDPServer::Init()
{
    int iSockFd = socket(AF_INET, SOCK_DGRAM|SOCK_NONBLOCK, IPPROTO_UDP);
    if (iSockFd == -1)
    {
        printf("socket error, %s\n", strerror(errno));
        return -1;
    }

    int iErr = bind(iSockFd, (const struct sockaddr*)&m_refParam.stAddr, sizeof(m_refParam.stAddr));
    if (iSockFd == -1)
    {
        printf("bind error, %s\n", strerror(errno));
        close(iSockFd);
        return -1;
    }

    m_iSockFd = iSockFd;

    return 0;
}

void CNetperfUDPServer::Run()
{
    fd_set stRFds;
    int32_t iRet;
    char acBuf[4096];

    while (true)
    {
        FD_ZERO(&stRFds);
        FD_SET(m_iSockFd, &stRFds);

        if (m_refParam.uiTimeout != 0)
        {
            struct timeval stTV;
            stTV.tv_sec = m_refParam.uiTimeout/1000000;
            stTV.tv_usec = m_refParam.uiTimeout%1000000;
            iRet = select(m_iSockFd + 1, &stRFds, NULL, NULL, NULL);
            if (iRet == -1)
            {
                perror("select error");
                break;
            }
        }
        else
        {
            iRet = m_iSockFd + 1;
        }

        if (iRet > 0 && FD_ISSET(m_iSockFd, &stRFds))
        {
            sockaddr_in stPeerAddr;
            socklen_t uiAddrLen = sizeof(stPeerAddr);
            ssize_t lRcvLen = recvfrom(m_iSockFd, acBuf, sizeof(acBuf), 0, (sockaddr *)&stPeerAddr, &uiAddrLen);
            if (lRcvLen > 0)
            {
                (void)sendto(m_iSockFd, acBuf, lRcvLen, 0, (const sockaddr *)&stPeerAddr, uiAddrLen);
            }
        }
    }
}